package com.panopset.swing;

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

import com.panopset.InputState;

/**
 * Full screen window. Esc key always disposes it. Usually you would add an
 * animated panel, such as a com.panopset.gui.Osgw panel, using getFrame().
 *
 * Override load and save methods to load and save state, as needed.
 *
 * @author Karl Dinwiddie
 *
 */
public class FullScreenWindow {

    private InputState is;

    /**
     * Graphics environment.
     */
    private final GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();

    /**
     * Graphics device.
     */
    private final GraphicsDevice gd = ge.getDefaultScreenDevice();

    /**
     * Full screen window frame.
     */
    private final JFrame frame;

    /**
     * @return Full screen window frame.
     */
    public final JFrame getFrame() {
        return frame;
    }
    /**
     * @param inputState To report mouse and key events to.
     */
    public FullScreenWindow() {
        frame = new JFrame();
        frame.setUndecorated(true);
        frame.setAlwaysOnTop(true);
        frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());
        frame.setLocation(0, 0);
        frame.addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseDragged(final MouseEvent e) {
                getInputState().reportMouseDragged(e.getPoint());
            }

            @Override
            public void mouseMoved(final MouseEvent e) {
                getInputState().reportMouseMoved(e.getPoint());
            }

        });
        frame.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(final MouseEvent e) {
                getInputState().reportMouseClicked(e.getPoint());
            }

        });
        frame.addKeyListener(new KeyAdapter() {

            public void keyPressed(final KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    quit();
                } else {
                    getInputState().reportKeyPressed(e.getKeyCode());
                }
            }

            public void keyReleased(final KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                    // ignore.
                } else {
                    getInputState().reportKeyReleased(e.getKeyCode());
                }
            }

        });
    }

    /**
     * Override as needed to load state.
     */
    protected void load() {
    }

    /**
     * Override as needed to save state.
     */
    protected void save() {
    }

    /**
     * @return InputState.
     */
    public InputState getInputState() {
        if (is == null) {
            is = new InputState();
        }
        return is;
    }
    /**
     * Load state and show the full screen window.
     */
    public final void show() {
        load();
        frame.setVisible(true);
        gd.setFullScreenWindow(frame);
    }

    /**
     * Dispose the full screen window and save state.
     */
    public final void quit() {
        save();
        Osgw.close();
        gd.setFullScreenWindow(null);
        frame.dispose();
    }
}
